#include "ErrorExit.h"
#include <memory>

using std::unique_ptr;

namespace SubPlayer
{
    void ErrorExit::ShowMessage(const LPCWSTR lpszFunction, boolean exit)
    { 
        // Retrieve the system error message for the last-error code
        LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
        DWORD dw = GetLastError(); 

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );

        // Display the error message and exit the process

        lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
        StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); 
        MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

        LocalFree(lpMsgBuf);
        LocalFree(lpDisplayBuf);
        if (exit) {
            ExitProcess(dw); 
        }
    }

    void ErrorExit::ShowMessage(const LPCSTR lpszFunction, boolean exit)
    {
        wstring functionName;
        if (charToWChar(lpszFunction, functionName) != 0) {
            functionName = wstring(L"Unknown function");
        }
        ShowMessage(functionName.c_str(), exit);
    }

    errno_t charToWChar(const char* text, wstring& wideStr)
    {
        size_t size = strlen(text) + 1;
        wchar_t* wa = new wchar_t[size];
        size_t converted;
        errno_t error = mbstowcs_s(&converted , wa, size,  text, size-1);
        if (error != 0) {
            wa = L"";
        }
        wideStr = wstring(wa);
        delete [] wa;
        return error;
    }

}